#include<stdio.h>
#include<unistd.h>
#include<wait.h>
#include<stdlib.h>

/*
int main()
{
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return 0;
    }
    //子进程
    else if(id==0)
    {
        int cnt=5;
        while(cnt)
        {
            printf("子进程：pid: %d ,ppid: %d,cnt :%d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        //进程开始5秒后销毁
        exit(0);

    }
    //父进程
    else
    {
        int cnt=10;
        while(cnt)
        {
            printf("父进程：pid: %d ,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        
        //5秒后，子进程变成僵尸进程，进程等待
        //先使用wait(),传入NULL表示不关心子进程返回状态
        //成功 返回被等待进程pid，失败 返回-1
        pid_t ret=wait(NULL);
        if(ret==id)
        {
            printf("成功回收子进程pid: %d\n",ret);
        }
        sleep(5);
    }
    return 0;
}
*/

/*

//第二个参数,status
int main()
{

    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return 0;
    }
    //子进程
    else if(id==0)
    {
        int cnt=5;
        while(cnt)
        {
            printf("子进程：pid: %d ,ppid: %d,cnt :%d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        //进程开始5秒后销毁
        exit(12);  //退出码改为12


    }
    //父进程
    else
    {
        int cnt=10;
        while(cnt)
        {
            printf("父进程：pid: %d ,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        
        
        //5秒后，子进程变成僵尸进程，进程等待
        //先使用wait(),传入NULL表示不关心子进程返回状态
        //成功 返回被等待进程pid，失败 返回-1
       int status=0;
       while(1)
       {

            printf("父进程：pid: %d ,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
        pid_t ret=waitpid(-1,&status,WNOHANG);
         
        //子进程结束
        if(ret==id)
        {
            //取出退出码和终止信号
            printf("成功回收子进程pid: %d，退出码exit_code：%d ,退出信号exit_sig :%d\n",ret,(status>>8)&0xff,status&0x7f);
            break;
        }
        //子进程未结束
        else if(ret==0)
        {
            printf("还没有回收成功，继续等\n");
        }
        else
        {
            //等待失败
            printf("等待失败\n");
            break;
        }
        sleep(1);
       } 
     }
    return 0;
}

*/
#include<string.h>
void task1()
{
    printf("任务1\n");
}
void task2()
{
    printf("任务2\n");
}

void task3()
{
    printf("任务3\n");
}

typedef void (*Fun_t)();//将void(*)() 定义为Fun_t函数指针

//
Fun_t taskarray[10];   //函数指针数组

void Init_task()
{
    memset(taskarray,0,10);
    taskarray[0]=task1;
    taskarray[1]=task2;
    taskarray[2]=task3;
}


//加入调用函数任务
int main()
{

    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return 0;
    }
    //子进程
    else if(id==0)
    {
        int cnt=5;
        while(cnt)
        {
            printf("子进程：pid: %d ,ppid: %d,cnt :%d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        //进程开始5秒后销毁
        exit(12);  //退出码改为12

    }
    //父进程
    else
    {
        Init_task();
        int cnt=10;
        /*while(cnt)
        {
            printf("父进程：pid: %d ,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        */
        
        //5秒后，子进程变成僵尸进程，进程等待
        //先使用wait(),传入NULL表示不关心子进程返回状态
        //成功 返回被等待进程pid，失败 返回-1
       int status=0;
       while(1)
       {

            printf("父进程：pid: %d ,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
        pid_t ret=waitpid(-1,&status,WNOHANG);
         
        //子进程结束
        if(ret==id)
        {
            //取出退出码和终止信号
            printf("成功回收子进程pid: %d，退出码exit_code：%d ,退出信号exit_sig :%d\n",ret,(status>>8)&0xff,status&0x7f);
            break;
        }
        //子进程未结束
        else if(ret==0)
        {
            int i=0;
            //printf("还没有回收成功，继续等\n");
            for(i=0;taskarray[i]!=NULL;i++)
            {
                taskarray[i]();
            }
        }
        else
        {
            //等待失败
            printf("等待失败\n");
            break;
        }
        sleep(1);
       } 
     }
    return 0;
}














































